﻿package com.morefuntek.mail;

import java.util.Properties;
import java.util.logging.Logger;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

public class MailSender {
	Logger log = Logger.getAnonymousLogger();

	private MimeMessage mimeMsg; // MIME邮件对象

	private Session session; // 邮件会话对象

	private Properties props; // 系统属性

	// private boolean needAuth = false; // smtp是否需要认证

	private String username = ""; // smtp认证用户名

	private String password = ""; // smtp认证用密码

	private Multipart mp; // Multipart对象,邮件内容,标题,附件等内容均添加到其中后再生成MimeMessage对象

	private MailSender(String smtp) {
		setSmtpHost(smtp);
		createMimeMessage();
	}

	/**
	 * 设置smtp主机名
	 * 
	 * @param hostName
	 *            (mail.morefuntek.com)
	 */
	public void setSmtpHost(String hostName) {

		log.info("设置系统属性：mail.smtp.host = " + hostName);

		if (props == null)
			props = System.getProperties(); // 获得系统属性对象

		props.put("mail.smtp.host", hostName); // 设置SMTP主机

	}

	/**
	 * 创建MIME邮件对象
	 * 
	 * @return
	 */
	public boolean createMimeMessage() {
		try {
			log.info("准备获取邮件会话对象！");
			session = Session.getDefaultInstance(props, null); // 获得邮件会话对象
		} catch (Exception e) {
			log.warning("获取邮件会话对象时发生错误！" + e);
			return false;
		}

		try {
			log.info("准备创建MIME邮件对象！");
			mimeMsg = new MimeMessage(session); // 创建MIME邮件对象
			mp = new MimeMultipart();

			return true;
		} catch (Exception e) {
			log.warning("创建MIME邮件对象失败！" + e);
			return false;
		}

	}

	/**
	 * 设置邮件服务器是否需要身份认证
	 * 
	 * @param need
	 */
	public void setNeedAuth(boolean need) {
		log.info("设置smtp身份认证：mail.smtp.auth = " + need);

		if (props == null)
			props = System.getProperties();
		if (need) {
			props.put("mail.smtp.auth", "true");
		} else {
			props.put("mail.smtp.auth", "false");
		}

	}

	/**
	 * 设置登陆邮件服务器的用户名、密码
	 * 
	 * @param name
	 *            steve.wang
	 * @param pass
	 *            123456
	 */
	public void setNamePass(String name, String pass) {
		username = name;
		password = pass;
	}

	/**
	 * 设置邮件主题
	 * 
	 * @param mailSubject
	 *            每日统计数据
	 * @return
	 */
	public boolean setSubject(String mailSubject) {
		log.info("设置邮件主题！");
		try {
			mimeMsg.setSubject(mailSubject);
			return true;
		} catch (Exception e) {
			log.warning("设置邮件主题发生错误！");
			return false;
		}

	}

	/**
	 * 设置邮件内容
	 * 
	 * @param mailBody
	 * @return
	 */
	public boolean setBody(String mailBody) {
		try {
			BodyPart bp = new MimeBodyPart();
			bp.setContent("" + mailBody, "text/plain;charset=GB2312");
			mp.addBodyPart(bp);

			return true;
		} catch (Exception e) {
			log.warning("设置邮件正文时发生错误！" + e);
			return false;
		}
	}

	/**
	 * 增加邮件附件
	 * 
	 * @param filename
	 *            附件文件名（全路径或相对路径）
	 * @return
	 */
	public boolean addFileAffix(String filename) {
		log.info("增加邮件附件：" + filename);
		try {
			BodyPart bp = new MimeBodyPart();
			FileDataSource fileds = new FileDataSource(filename);
			bp.setDataHandler(new DataHandler(fileds));
			bp.setFileName(MimeUtility.encodeWord(fileds.getName(), "GB2312",
					null));
			// bp.setFileName(fileds.getName());
			mp.addBodyPart(bp);

			return true;
		} catch (Exception e) {
			log.warning("增加邮件附件：" + filename + "发生错误！" + e);
			return false;
		}
	}

	/**
	 * 设置发信人
	 * 
	 * @param from
	 * @return
	 */
	public boolean setFrom(String from) {
		log.info("设置发信人！");
		try {
			mimeMsg.setFrom(new InternetAddress(from)); // 设置发信人
			return true;
		} catch (Exception e) {
			log.warning(e.getMessage());
			return false;
		}

	}

	/**
	 * 设置收件人
	 * 
	 * @param to
	 * @return
	 */
	public boolean setTo(String to) {
		if (to == null)
			return false;

		try {
			mimeMsg.setRecipients(Message.RecipientType.TO,
					InternetAddress.parse(to));

			return true;
		} catch (Exception e) {
			log.warning(e.getMessage());
			return false;
		}

	}

	/**
	 * 设置抄送
	 * 
	 * @param copyto
	 * @return
	 */
	public boolean setCopyTo(String copyto) {
		if (copyto == null)
			return false;

		try {
			mimeMsg.addRecipients(Message.RecipientType.CC,
					InternetAddress.parse(copyto));

			return true;
		} catch (Exception e) {
			log.warning(e.getMessage());
			return false;
		}
	}

	/**
	 * 发送一封邮件
	 * 
	 * @return
	 */
	public boolean sendout() {
		try {
			mimeMsg.setContent(mp);
			mimeMsg.saveChanges();
			log.info("正在发送邮件....");

			Session mailSession = Session.getInstance(props, null);

			Transport transport = mailSession.getTransport("smtp");

			transport.connect((String) props.get("mail.smtp.host"), username,
					password);
			// 主发
			transport.sendMessage(mimeMsg,
					mimeMsg.getRecipients(Message.RecipientType.TO));
			// 抄送
			transport.sendMessage(mimeMsg,
					mimeMsg.getRecipients(Message.RecipientType.CC));
			// transport.send(mimeMsg);

			log.info("发送邮件成功！");

			transport.close();
			return true;
		} catch (Exception e) {
			log.warning("邮件发送失败！" + e.getMessage());
			return false;
		}

	}

	private static String parseTo(String mailTo) {
		return mailTo.substring(0, mailTo.indexOf('@'));
	}

	public static boolean send(Mail mail) {
		MailSender themail = new MailSender(mail.getSmtpServer());
		themail.setNeedAuth(true);
		themail.setNamePass(mail.getAuthUser(), mail.getAuthPassword());

		if (!themail.setSubject(mail.getSubject()))
			return false;

		if (!themail.setBody(parseTo(mail.getTo()) + "，您好！\r\n\t"
				+ mail.getBody()))
			return false;

		if (!themail.setTo(mail.getTo()))
			return false;

		if (!themail.setFrom(mail.getFrom()))
			return false;

		for (String file : mail.getAttachFiles()) {
			if (!themail.addFileAffix(file))
				return false;
		}

		for (String copyTo : mail.getCopyTo()) {
			if (!themail.setCopyTo(copyTo))
				return false;
		}
		return themail.sendout();
	}
}
